#include "dir.h"

//membuat dir element baru dan alokasi memorinya
void createDirElmt(direlement * dirElmt){
	(*dirElmt).name = (char*) malloc (NAME_SIZE+1);
	emptyDirElmt(dirElmt);
}

//mengembalikan nilai true atau 1 bila direlement kosong
bool isDirElmtEmpty(direlement dirElmt){
	if(dirElmt.inode_no==0)
		return true;
	else
		return false;
}

//mengosongkan dir element
void emptyDirElmt(direlement* dirElmt){
	(*dirElmt).inode_no = 0;
	(*dirElmt).name = "";
}

//init menginisiasi dir_t yang baru
void createDir(dir_t* dir){
	(*dir).direlements = (direlement*) malloc ((MAX_DIR_ELMT+1)*sizeof(direlement));
	int i;
	for(i=0;i<MAX_DIR_ELMT;i++){
		createDirElmt(&((*dir).direlements[i]));
	}
}

//insert info inode baru ke direktori mengembalikan 0 kalau berhasil, mengembalikan 1 kalo gagal
//arg0 -> direktori yang akan diinsert sesuatu; arg1 -> i-node number (2byte); arg2 -> file/dir name (16byte);
bool insert(dir_t* dir, unsigned inode_no, char* name){
	int i = 0;
	while(!isDirElmtEmpty((*dir).direlements[i]) && i<MAX_DIR_ELMT){
		i++;
	}
	if(i<MAX_DIR_ELMT){
		//dir masih ada
		(*dir).direlements[i].inode_no = inode_no;
		(*dir).direlements[i].name = name;
		return true;
	} else {
		//dir penuh
		return false;
	}
}

//delete info di sebuah dir, mengembalikan 0 kalau berhasil, mengembalikan 1 kalo gagal
//arg0 -> direktori yang akan diinsert sesuatu; arg1 -> i-node number (2byte);
bool delete(dir_t* dir,unsigned inode_no){
	int i = 0;
	while((*dir).direlements[i].inode_no!=inode_no && i<MAX_DIR_ELMT){
		i++;
	}
	if(i<MAX_DIR_ELMT){
		emptyDirElmt(&((*dir).direlements[i]));
		return true;
	} else {
		//yang mau di delete g ada
		return false;
	}
}

//membaca direktori berdasarkan inode numbernya
void readDir(dir_t* dir, FILE* hdd,unsigned inode_no){
	block_t block = readBlock(hdd,getDirAddr(hdd,inode_no));
	int i = 0, j = 0;
	while(i < 4000){
		char * temp = (char*) malloc(3);
		temp[0] = block.bytes[i];
		temp[1] = block.bytes[i+1];
		temp[2] = '\0';
		if(stringToU(temp)==0) return; //bila inode no = 0, keluar
		dir->direlements[j].inode_no = stringToU(temp);
		dir->direlements[j].name = (char*) malloc(17);
		int k;
		for(k = 0; k < 17; k++){
			dir->direlements[j].name[k] = block.bytes[i+2+k];
		}
		dir->direlements[j].name[k] = '\0';
		i+=18;
		j++;
	}
}

//menuliskan direktori berdasarkan inode numbernya
void writeDir(dir_t dir, FILE* hdd, unsigned inode_no, unsigned parent_no, unsigned long addrBlock){
	block_t block;
	block.addr = addrBlock;
	char* temp;
	/*
	//inisiasi dir dengan alamat inode diri sendiri
	temp = uToString(inode_no);
	block.bytes[0] = temp[0];
	block.bytes[1] = temp[1];
	block.bytes[17] = '.';
	//inisiasi parent dir
	temp = uToString(parent_no);
	block.bytes[18] = temp[0];
	block.bytes[19] = temp[1];
	block.bytes[34] = '.';
	block.bytes[35] = '.';
	//baru isi yang lainnya
	*/
	int i = 0, j = 0; //i -> perulangan elemen dir, j -> perulangan bytes block
	while(dir.direlements[i].inode_no!=0){
		temp = uToString(dir.direlements[i].inode_no);
		block.bytes[j] = temp[0];
		block.bytes[++j] = temp[1];
		int k = 0;
		while(k<17 && dir.direlements[i].name[k]!='\0'){
			block.bytes[++j] = dir.direlements[i].name[k];
			k++;
		}
		i++;
	}
	writeBlock(hdd,block);
}

dir_t getDirFromPath(FILE* hdd,unsigned cwd[500]){
	dir_t dir;
	int i = 0;
	while(cwd[i]!=0){
		i++;
	}
	readDir(&dir,hdd,cwd[i-1]);
	return dir;
}
